﻿@inject IAccessTokenProvider _accessTokenProvider
@inject Settings _settings
@inject NavigationManager _navigationManager

<CascadingValue Value="_orderState">
    @ChildContent
</CascadingValue>

@code {

    private HubConnection? _hubConnection;
    private OrderState? _orderState;

    [Parameter]
    public RenderFragment ChildContent { get; set; } = null!;

    [CascadingParameter]
    private Task<AuthenticationState> AuthenticationStateTask { get; set; } = null!;

    protected override async Task OnParametersSetAsync()
    {
        var authenticationState = await AuthenticationStateTask;
        if (authenticationState.User!.Identity!.IsAuthenticated)
        {
            await ConnectToNotificationHub();
        }
    }

    private async Task ConnectToNotificationHub()
    {
        if (_hubConnection == null || _hubConnection.State == HubConnectionState.Disconnected)
        {
            _hubConnection = new HubConnectionBuilder()
                .WithUrl($"{_settings.ApiGatewayUrlExternal}/hub/notificationhub", options =>
                {
                    options.AccessTokenProvider = GetAccessTokenAsync;
                })
                .WithAutomaticReconnect()
                .Build();

            _hubConnection.On<OrderState>("UpdatedOrderState", OnUpdatedOrderState);

            await _hubConnection.StartAsync();
        }
    }

    private async Task<string?> GetAccessTokenAsync()
    {
        var accessTokenResult = await _accessTokenProvider.RequestAccessToken();
        if (accessTokenResult.TryGetToken(out AccessToken accessToken))
        {
            return accessToken.Value;
        }

        _navigationManager.NavigateTo("authentication/login");

        return null;
    }

    private void OnUpdatedOrderState(OrderState orderState)
    {
        // Set cascading parameter to let descendants know that the order state
        // has changed.
        _orderState = orderState;

        StateHasChanged();
    }
}
